package ue

import (
	"crypto/rsa"
	"cybertwin/utils/cryptotools"
	"cybertwin/utils/protocol"
	"fmt"
	"sync"

	"github.com/panjf2000/gnet/v2"
	log "github.com/sirupsen/logrus"
)

const (
	CT_IP = "127.0.0.1"
	// CT_PORT = "30202"
	CT_PORT = "8888"
)

type ApClient struct {
	gnet.BuiltinEventEngine
	eng          gnet.Engine
	shutdown     bool
	Finish       bool
	r1           int    // 随机数r1
	Hid          string // 客户端自己应该知道自己的hid是多少
	Ueid         string
	ck1          []byte
	uePrivateKey *rsa.PrivateKey // 设备自身的密钥对
	apPublicKey  *rsa.PublicKey
	Token        []byte
	R3           int
	Wg           *sync.WaitGroup
	Ct_ip        string
	Ct_port      string
}

func (client *ApClient) OnBoot(eng gnet.Engine) (action gnet.Action) {
	log.Infoln("[OnBoot]-ap client starting")
	client.eng = eng
	client.shutdown = false
	client.Finish = false
	client.uePrivateKey = cryptotools.RSA_LoadPrivateKey("./ca/ue", "ue_sk_1.pem")
	return
}

func (client *ApClient) OnOpen(conn gnet.Conn) (out []byte, action gnet.Action) {
	// 连接开启后，直接发送access hello请求
	err := AccessHello(conn)
	if err != nil {
		log.Warnln("[ApClient OnOpen]-AccessHello failed")
		action = gnet.Close
	}
	fmt.Println("-----------------------")
	return
}

func (client *ApClient) OnTraffic(conn gnet.Conn) (action gnet.Action) {
	data, typeName, _, err := protocol.CodecUtils.AccessProtocolCodec.Decode(conn)
	if err != nil {
		action = gnet.None
		//log.Warnln("[ApClient OnTraffic]-Decode错误:", err.Error())
		return
	}
	switch typeName {
	case protocol.TYPE_ACCESSHELLO_RESP.GetName():
		err := client.handler_ACCESSHELLO_RESP(data, conn)
		if err != nil {
			log.Errorln("[ApClient OnTraffic]-[TYPE_ACCESSHELLO_RESP]-", err.Error())
		}
		fmt.Println("-----------------------")
	case protocol.TYPE_HID_CHECK_RESP.GetName():
		err := client.handler_HID_CHECK_RESP(data, conn)
		if err != nil {
			log.Errorln("[ApClient OnTraffic]-[TYPE_HID_CHECK_RESP]-", err.Error())
		}
		fmt.Println("-----------------------")
	case protocol.TYPE_TOKEN_APPLY_RESP.GetName():
		err := client.handler_TOKEN_APPLY_RESP(data, conn)
		if err != nil {
			log.Errorln("[ApClient OnTraffic]-[TYPE_TOKEN_APPLY_RESP]-", err.Error())
		}
		fmt.Println("-----------------------")
		client.Wg.Done() // 和ap的交流结束，接下来和cybertwin进行交流
	}
	return
}
